home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / fish / 676-700 / 680 / atap / sourcecode / unpackfntii.c < prev    next >
C/C++ Source or Header  |  1995-03-18  |  7KB  |  269 lines

  1. /* Welcome to Gordon Fecyk's very first real C program.
  2.  
  3.    This is a Macintosh resource file unpacker with special
  4.    searches and routines for FOND, FONT, and NFNT resources.
  5.  
  6.    Both pure resource files and MacBinary files will unpack
  7.    as I've put enough smarts in this thing to know the difference.
  8.  
  9.    Coming one of these days: font charset remapping and actual conversion.
  10. */
  11.  
  12. #include <stdio.h>
  13. #include <proto/exec.h>        
  14.  
  15. /* This program is the product of learning two different styles of
  16.    C programming and trying to mix them.  Kids, don't try this
  17.    at home. */
  18.  
  19. /* Some defines for resource types */
  20. #define    FOND    0x464F4E44
  21. #define FONT    0x464F4E54
  22. #define NFNT    0x4E464E54
  23. /* These let me cheat; I can read resource    */
  24. /* types as ULONGs instead of chars!        */
  25.  
  26. /* My prototypes: */
  27.  
  28. void    RemoveSpaces(char *charString);
  29. char    *freadline(FILE *sourceFile);
  30. long    ReadInt(FILE *filePointer, int numBytes);
  31.  
  32. int main(int argc, char *argv[])
  33.  
  34. {
  35.     ULONG    resDOffset,resMOffset,resDLength,resMLength,resOffset;
  36.     ULONG    resType,resTOrder[3];
  37.     UWORD    numRTType[3],refLOffsets[3],numRTypes,resTLOffset,resNLOffset,test;
  38.     WORD    resID,resNLength,numFonts,fontSize,fontType;
  39.     char    resName[24];
  40.                 /* All documented in Inside Macintosh I */
  41.  
  42.     char    *fileName;
  43.     FILE    *resFile;
  44.     char    resData,outName[30],inName[30],fontName[30],;
  45.     FILE    *outFile,*fondList;
  46.     ULONG    resLength,index,index2,resDPosition=0,resStart=0;
  47.  
  48.     if (argc!=2)
  49.     {
  50.         printf("Usage: %s SuitcaseName[.mbin]\n\n",argv[0]);
  51.         printf("The Suitcase file must be created from Font/DA Mover V3.8\n");
  52.         printf("or better, and be a pure resource file or a MacBinary file.\n");
  53.         SafeExit();
  54.     }
  55.  
  56.     fileName=argv[1];        /* Passed through CLI/Shell    */
  57.  
  58.     resFile=fopen(fileName,"r");    /* No BPTRs here!        */
  59.  
  60.     if(resFile==0)
  61.     {
  62.         printf("%s not found.\n",fileName);
  63.         printf("Usage: %s SuitcaseName[.mbin]\n",argv[0]);
  64.         SafeExit();
  65.     }
  66.  
  67.     resDOffset=ReadInt(resFile,4);
  68.     if (resDOffset!=256)
  69.     {
  70.         fseek(resFile,128,0);
  71.         resDOffset=ReadInt(resFile,4);  /* That's better    */
  72.         resStart=128;
  73.         if (resDOffset!=256)        /* Check one more time    */
  74.         {
  75.             printf("%s is not a font suitcase file!\n",fileName);
  76.             fclose(resFile);
  77.             SafeExit();
  78.         }
  79.     }
  80.     resMOffset=ReadInt(resFile,4);
  81.     resDLength=ReadInt(resFile,4);
  82.     resMLength=ReadInt(resFile,4);
  83.  
  84.     fseek(resFile,resStart+resDOffset,0);    /* Jump to resDOffset     */
  85.  
  86. /* This will extract the individual resources and name them.
  87.    Empty resources (resLength=0) are ignored. */
  88.  
  89.     mkdir("T:ResFiles","w");
  90.     while(resDPosition < resDLength)
  91.     {
  92.         resLength=ReadInt(resFile,4);
  93.         if (resLength!=0)
  94.         {
  95.             sprintf(outName,"T:ResFiles/RES%ld",resDPosition);
  96.             outFile=fopen(outName,"w");
  97.             for (index=0;index < resLength;index++)
  98.             {
  99.                 resData=fgetc(resFile);
  100.                 fputc(resData,outFile);
  101.             }
  102.             fclose(outFile);
  103.         }
  104.         resDPosition=resDPosition+resLength+4;
  105.     }
  106.  
  107. /* With extraction out of the way, time to parse the resource map. */
  108.  
  109.     fseek(resFile,resStart+resMOffset+24,0);
  110.  
  111.     resTLOffset=ReadInt(resFile,2);
  112.     resNLOffset=ReadInt(resFile,2);
  113.     resStart=ftell(resFile);        /* Start of Res type list */
  114.     numRTypes=ReadInt(resFile,2);
  115.  
  116.     index2=0;
  117.     for (index=0;index<=numRTypes;index++)
  118.     {
  119.         resType=ReadInt(resFile,4);
  120.         switch(resType)
  121.         {
  122.         case FONT:
  123.         case NFNT:
  124.         case FOND:
  125.             resTOrder[index2]=resType;
  126.             numRTType[index2]=ReadInt(resFile,2);
  127.             refLOffsets[index2]=ReadInt(resFile,2);
  128.             index2++;
  129.             break;
  130.  
  131.         default:
  132.             fseek(resFile,4,1);
  133.             break;
  134.         }
  135.     }
  136.  
  137. /* Where the font manager resources are is now saved. */
  138. /* Next, we rename the files in T:ResFiles by resource type and ID. */
  139.  
  140.     for (index=0;index<3;index++)
  141.     {
  142.         fseek(resFile,resStart+refLOffsets[index],0);
  143.         for (index2=0;index2<=numRTType[index];index2++)
  144.         {
  145.             resID=ReadInt(resFile,2);
  146.             resNLOffset=ReadInt(resFile,2);
  147.             fseek(resFile,1,1);
  148.             resOffset=ReadInt(resFile,3);    /* That's why I like my own int reader! */
  149.             fseek(resFile,4,1);
  150.  
  151.             sprintf(inName,"T:ResFiles/RES%ld",resOffset);
  152.  
  153.             switch(resTOrder[index])
  154.             {
  155.             case FOND:
  156.                 sprintf(outName,"T:ResFiles/Fond %ld",resNLOffset);
  157.                 break;
  158.  
  159.             case FONT:
  160.             case NFNT:
  161.                 sprintf(outName,"T:ResFiles/Font %ld",resID);
  162.                 break;
  163.             }
  164.             rename(inName,outName);
  165.         }
  166.     }
  167.  
  168. /* Wicked... On to the name list... Only FONDs are named here, but this
  169.    could be altered.  A rename only occurs if the name offset matches the
  170.    name offset in a FOND filename.  Fortunately, C programs don't croak if a
  171.    rename() fails.  This makes this part easy to code. */
  172.  
  173.     resStart=ftell(resFile);        /* Start of res name list */
  174.     fondList=fopen("T:ResFiles/FondNameList.txt","w");
  175.  
  176.     while (!feof(resFile))
  177.     {
  178.         resNLOffset=ftell(resFile)-resStart;
  179.         resNLength=ReadInt(resFile,1);    /* My ReadInt is great! */
  180.         fread(resName,1,resNLength,resFile);
  181.         resName[resNLength]=0;    /* Let's not forget that null */
  182.         sprintf(inName,"T:ResFiles/Fond %ld",resNLOffset);
  183.         RemoveSpaces(resName);
  184.         sprintf(outName,"T:ResFiles/%s",resName);
  185.          test=rename(inName,outName);
  186.         if (test==0)
  187.             fprintf(fondList,"%s\n",resName); 
  188.     }
  189.  
  190.     fclose(resFile);
  191.     fclose(fondList);
  192.  
  193. /* Now to interpret the FONDs and determine which ones are what. */
  194.  
  195.     fondList=fopen("T:ResFiles/FondNameList.txt","r");
  196.     mkdir("T:UnpackedFonts","w");
  197.  
  198.     strcpy(fontName,freadline(fondList));
  199.     while (!feof(fondList))
  200.     {
  201.         strcpy(resName,"T:ResFiles/");
  202.         strcat(resName,fontName);
  203.         resFile=fopen(resName,"r");
  204.         fseek(resFile,52,0);
  205.         numFonts=ReadInt(resFile,2);
  206.         for (index=0;index<=numFonts;index++)
  207.         {
  208.             fontSize=ReadInt(resFile,2);
  209.             fontType=ReadInt(resFile,2);
  210.             resID=ReadInt(resFile,2);
  211.             if (fontType==0)
  212.             {
  213.                 sprintf(inName,"T:ResFiles/Font %d",resID);
  214.                 sprintf(outName,"T:UnpackedFonts/%s.%d",fontName,fontSize);
  215.                 rename(inName,outName);
  216.             }
  217.         }
  218.         fclose(resFile);
  219.         sprintf(inName,"T:ResFiles/%s",fontName);
  220.         remove(inName);
  221.         strcpy(fontName,freadline(fondList));
  222.     }
  223.     fclose(fondList);
  224.     remove("T:ResFiles/FondNameList.txt");
  225.     rmdir("T:ResFiles");
  226.  
  227. /* All cleaning up is done, time to quit. */
  228.  
  229.     SafeExit();
  230. };
  231.  
  232.  
  233. /* Simple safe exit routine */
  234.  
  235. SafeExit()
  236.  
  237. {
  238.     exit(0);
  239. };
  240.  
  241. void RemoveSpaces(char *charString)
  242.  
  243. /* This'll go through a string (typically a font name) and strip
  244.    the spaces from it. The original string is affected by this,
  245.    and the string length will be shorter or the same length. */
  246.  
  247. {
  248.  
  249.     int index,charOffset,strLength;
  250.  
  251.     strLength=strlen(charString);
  252.     charOffset=0;
  253.     for (index=0;index<strLength;index++)
  254.     {
  255.         if (charString[index]==32)
  256.         {
  257.             charOffset++;
  258.             index++;
  259.         }
  260.  
  261.         charString[index-charOffset]=charString[index];
  262.     }
  263.     charString[strLength-charOffset]=0;
  264.     return;
  265. };
  266.  
  267. #include "ReadInt.c"
  268. #include "freadline.c"        /* Borrowed from ConvertAFM */
  269.